package com.kmsoft.gateway.domain;

import lombok.Data;
import lombok.Getter;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

@Getter
public class GatewayConfigDomain {

    // 路由Id
    private String routeId;
    // 类型(1：绝对路径，0：根据服务serverId匹配)
    private String routeType;
    // url地址
    private String routeUrl;
    // 规则
    private String routePattern;

    public GatewayConfigDomain(String routeId, String routeType, String routeUrl, String routePattern) {
        this.routeId = routeId;
        this.routeType = routeType;
        this.routeUrl = routeUrl;
        this.routePattern = routePattern;
    }

    public void loadRoute(RouteDefinitionWriter routeDefinitionWriter){
        RouteDefinition definition = new RouteDefinition();
        Map<String, String> predicateParams = new HashMap<>(8);
        PredicateDefinition predicate = new PredicateDefinition();
        FilterDefinition filterDefinition = new FilterDefinition();
        Map<String, String> filterParams = new HashMap<>(8);
        // 如果配置路由type为0的话,则从注册中心获取服务
        URI uri;
        if ("0".equals(routeType)) {
            uri = UriComponentsBuilder.fromUriString("lb://" + routeUrl + "/").build().toUri();
        } else {
            uri = UriComponentsBuilder.fromHttpUrl(routeUrl).build().toUri();
        }
        // 定义的路由唯一的id
        definition.setId(routeId);
        predicate.setName("Path");
        //路由转发地址
        predicateParams.put("pattern", routePattern);
        predicate.setArgs(predicateParams);

        // 名称是固定的, 路径去前缀
        filterDefinition.setName("StripPrefix");
        filterParams.put("_genkey_0", "1");
        filterDefinition.setArgs(filterParams);
        definition.setPredicates(Collections.singletonList(predicate));
        definition.setFilters(Collections.singletonList(filterDefinition));
        definition.setUri(uri);
        routeDefinitionWriter.save(Mono.just(definition)).subscribe();
    }
}
